module Test where
 
import Hw2
import Text.Printf

-- Part 1 --
data Fl b = (Fl b) :< b | El
    deriving (Show)

data Fr b = b :> (Fr b) | Er
    deriving (Show)

-- Part 2 --
instance (Eq k, Eq v) => Eq (BST k v) where
    t1 == t2 = (toList t1) == (toList t2)

instance (Show k, Show v) => Show (BST k v) where
    show x = let str = (showTree x 0)
              in take ((length str)-1) str

showTree :: (Enum h, Num h, Show v, Show k) => BST k v -> h -> String
showTree Emp h = ((spaces h) ++ "Null\n")
showTree (Bind k v l r) h = (spaces h) ++ show k ++ ": " ++ show v ++ "\n"
                            ++ showTree l (h+1)
                            ++ showTree r (h+1)

spaces h = foldl (\a _ -> a ++ "|  " ) "" [1..h]

ofList = foldl (\t (k,v) -> insert k v t) Emp
toList = foldBST (\k v l r -> l ++ [(k, v)] ++ r) []

foldBST ::  (k -> v -> t -> t -> t) -> t -> BST k v -> t
foldBST f b Emp            = b 
foldBST f b (Bind k v l r) = f k v (foldBST f b l) (foldBST f b r)

insert ::  Ord k => k -> v -> BST k v -> BST k v
insert k v Emp = Bind k v Emp Emp
insert k v (Bind k' v' l r) 
  | k == k' = Bind k v l r
  | k <  k' = Bind k' v' (insert k v l) r
  | otherwise = Bind k' v' l (insert k v r)

nextLine = putStrLn("")

-- Main --
mainT :: IO ()
mainT = do 
    putStrLn("=== Part 1. ===")
    let myList = ["A","B","C"]
    putStrLn("1. myFoldl")
    putStrLn(show $ foldl (++) "D" myList)
    putStrLn(show $ myFoldl (++) "D" myList)
    nextLine

    putStrLn("2. myReverse")
    putStrLn(show $ myList)
    putStrLn(show $ myReverse myList)
    nextLine

    putStrLn("3. myFoldr")
    putStrLn(show $ foldr (++) "D" myList)
    putStrLn(show $ myFoldr (++) "D" myList)
    nextLine    

    putStrLn("4. myFoldl2")
    putStrLn(show $ foldl (++) "D" myList)
    putStrLn(show $ myFoldl2 (++) "D" myList)
    nextLine

    putStrLn("=== Part 2. ===")
    let t0 = ofList [("b",5.25), ("a",4.50), ("c",2.75)]
    let t1 = ofList [("d",11), ("e",25), ("f",13), ("a",2), ("b",9), ("c",4)]
    let t2 = ofList [("e",1), ("d",2), ("f",3), ("b",4), ("h",5), ("a",6), ("c",7), ("g",8), ("i",9)]
    putStrLn("Small tree t0:")
    print $ t0
    nextLine

    putStrLn("delete \"c\" t1")
    print $ delete "c" t0
    nextLine
     
    putStrLn("delete \"b\" t1")
    print $ delete "b" t0
    nextLine

    putStrLn("delete \"a\" t1")
    print $ delete "a" t0
    nextLine
    
    putStrLn("delete \"f\" t1 (No such key in the tree)")
    print $ delete "f" t0
    nextLine

    putStrLn("Big tree t2:")
    print $ t2
    nextLine

    putStrLn("delete \"e\" t2 (root)")
    print $ delete "e" t2
    nextLine
 
    putStrLn("delete \"d\" t2 (root of branch)")
    print $ delete "d" t2
    nextLine
    
    putStrLn("delete \"g\" t2 (leaf)")
    print $ delete "g" t2
    nextLine
